package com.uniflow.service;

import com.uniflow.common.PageResult;
import com.uniflow.entity.Role;
import com.uniflow.mapper.RoleMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.time.LocalDateTime;
import java.util.*;

/**
 * 角色服务类
 */
@Service
@Transactional
public class RoleService {
    
    @Autowired
    private RoleMapper roleMapper;
    
    @Autowired
    private PermissionService permissionService;
    
    /**
     * 分页查询角色列表
     */
    public PageResult<Role> getRoleList(int pageNum, int pageSize, String keyword) {
        List<Role> allRoles = roleMapper.selectList(keyword);
        long total = roleMapper.selectCount(keyword);
        
        // 手动分页
        int fromIndex = (pageNum - 1) * pageSize;
        int toIndex = Math.min(fromIndex + pageSize, allRoles.size());
        List<Role> pagedRoles = fromIndex < allRoles.size() ? 
             allRoles.subList(fromIndex, toIndex) : new ArrayList<>();
        
        return new PageResult<Role>(pageNum, pageSize, total, pagedRoles);
    }
    
    /**
     * 获取所有角色
     */
    public List<Role> getAllRoles() {
        return roleMapper.selectAll();
    }
    
    /**
     * 根据ID查询角色
     */
    public Role getRoleById(String id) {
        return roleMapper.selectById(id);
    }
    
    /**
     * 根据名称查询角色
     */
    public Role getRoleByName(String name) {
        return roleMapper.selectByName(name);
    }
    
    /**
     * 根据用户ID查询角色列表
     */
    public List<Role> getRolesByUserId(String userId) {
        return roleMapper.selectByUserId(userId);
    }
    
    /**
     * 创建角色
     */
    public Role createRole(Role role) {
        // 生成ID
        role.setId(UUID.randomUUID().toString().replace("-", ""));
        
        // 设置创建时间
        LocalDateTime now = LocalDateTime.now();
        role.setCreatedAt(now);
        role.setUpdatedAt(now);
        
        // 检查名称是否重复
        if (roleMapper.existsByName(role.getName(), null)) {
            throw new RuntimeException("角色名称已存在");
        }
        
        roleMapper.insert(role);
        return role;
    }
    
    /**
     * 批量创建角色
     */
    public List<Role> createRoles(List<Role> roles) {
        LocalDateTime now = LocalDateTime.now();
        
        for (Role role : roles) {
            role.setId(UUID.randomUUID().toString().replace("-", ""));
            role.setCreatedAt(now);
            role.setUpdatedAt(now);
        }
        
        roleMapper.insertBatch(roles);
        return roles;
    }
    
    /**
     * 更新角色
     */
    public Role updateRole(Role role) {
        Role existingRole = roleMapper.selectById(role.getId());
        if (existingRole == null) {
            throw new RuntimeException("角色不存在");
        }
        
        // 检查名称是否重复（排除自己）
        if (StringUtils.hasText(role.getName()) && 
            !role.getName().equals(existingRole.getName()) &&
            roleMapper.existsByName(role.getName(), role.getId())) {
            throw new RuntimeException("角色名称已存在");
        }
        
        role.setUpdatedAt(LocalDateTime.now());
        roleMapper.updateById(role);
        
        return roleMapper.selectById(role.getId());
    }
    
    /**
     * 删除角色
     */
    public void deleteRole(String id) {
        Role role = roleMapper.selectById(id);
        if (role == null) {
            throw new RuntimeException("角色不存在");
        }
        
        // 检查角色是否被用户使用
        if (isRoleInUse(id)) {
            throw new RuntimeException("该角色正在被用户使用，无法删除");
        }
        
        roleMapper.deleteById(id);
    }
    
    /**
     * 批量删除角色
     */
    public void deleteRoles(List<String> ids) {
        for (String id : ids) {
            deleteRole(id);
        }
    }
    
    /**
     * 为用户分配角色
     */
    public void assignRoleToUser(String userId, String roleId) {
        // 检查角色是否存在
        Role role = roleMapper.selectById(roleId);
        if (role == null) {
            throw new RuntimeException("角色不存在");
        }
        
        // 检查是否已经分配
        if (hasRole(userId, role.getName())) {
            throw new RuntimeException("用户已拥有该角色");
        }
        
        roleMapper.assignRoleToUser(userId, roleId);
    }
    
    /**
     * 移除用户角色
     */
    public void removeRoleFromUser(String userId, String roleId) {
        roleMapper.removeRoleFromUser(userId, roleId);
    }
    
    /**
     * 清空用户所有角色
     */
    public void clearUserRoles(String userId) {
        roleMapper.clearUserRoles(userId);
    }
    
    /**
     * 批量为用户分配角色
     */
    public void batchAssignRolesToUser(String userId, List<String> roleIds) {
        // 先清空用户现有角色
        clearUserRoles(userId);
        
        // 分配新角色
        if (roleIds != null && !roleIds.isEmpty()) {
            roleMapper.batchAssignRolesToUser(userId, roleIds);
        }
    }
    
    /**
     * 检查用户是否拥有指定角色
     */
    public boolean hasRole(String userId, String roleName) {
        return roleMapper.hasRole(userId, roleName);
    }
    
    /**
     * 检查用户是否拥有指定权限
     */
    public boolean hasPermission(String userId, String permission) {
        return roleMapper.hasPermission(userId, permission);
    }
    
    /**
     * 检查角色是否被用户使用
     */
    public boolean isRoleInUse(String roleId) {
        List<Role> userRoles = roleMapper.selectByUserId(null); // 这里需要修改mapper方法
        // 简化实现：通过查询用户角色关联表来判断
        try {
            // 尝试删除角色，如果有外键约束会抛出异常
            // 这里应该有更好的实现方式，比如查询user_roles表
            return false; // 临时返回false，实际应该查询关联表
        } catch (Exception e) {
            return true;
        }
    }
    
    /**
     * 检查角色名称是否可用
     */
    public boolean isNameAvailable(String name, String excludeId) {
        if (!StringUtils.hasText(name)) {
            return false;
        }
        
        Role existing = roleMapper.selectByName(name);
        if (existing == null) {
            return true;
        }
        
        // 如果是更新操作，排除自己
        return StringUtils.hasText(excludeId) && existing.getId().equals(excludeId);
    }
    
    /**
     * 获取角色统计信息
     */
    public Map<String, Object> getRoleStatistics() {
        Map<String, Object> statistics = new HashMap<>();
        
        // 总角色数
        long totalCount = roleMapper.selectCount(null);
        statistics.put("totalCount", totalCount);
        
        // 系统内置角色数（假设以ROLE_开头的为系统角色）
        int systemRoleCount = countSystemRoles();
        statistics.put("systemRoleCount", systemRoleCount);
        
        // 自定义角色数
        statistics.put("customRoleCount", totalCount - systemRoleCount);
        
        // 被使用的角色数
        int usedRoleCount = countUsedRoles();
        statistics.put("usedRoleCount", usedRoleCount);
        
        // 未使用的角色数
        statistics.put("unusedRoleCount", totalCount - usedRoleCount);
        
        return statistics;
    }
    
    /**
     * 统计系统角色数量
     */
    private int countSystemRoles() {
        List<Role> allRoles = roleMapper.selectAll();
        int count = 0;
        
        for (Role role : allRoles) {
            if (role.getName() != null && role.getName().startsWith("ROLE_")) {
                count++;
            }
        }
        
        return count;
    }
    
    /**
     * 统计被使用的角色数量
     */
    private int countUsedRoles() {
        List<Role> allRoles = roleMapper.selectAll();
        int count = 0;
        
        for (Role role : allRoles) {
            if (isRoleInUse(role.getId())) {
                count++;
            }
        }
        
        return count;
    }
    
    /**
     * 获取用户的权限列表
     */
    public List<String> getUserPermissions(String userId) {
        // 使用PermissionService获取用户权限
        List<com.uniflow.entity.Permission> userPermissions = permissionService.getUserPermissions(userId);
        return userPermissions.stream()
            .map(com.uniflow.entity.Permission::getCode)
            .collect(java.util.stream.Collectors.toList());
    }
    
    /**
     * 获取用户的角色名称列表
     */
    public List<String> getUserRoleNames(String userId) {
        List<Role> userRoles = getRolesByUserId(userId);
        List<String> roleNames = new ArrayList<>();
        
        for (Role role : userRoles) {
            roleNames.add(role.getName());
        }
        
        return roleNames;
    }
}